# coding: utf-8
from typing import Union

from PySide6.QtCore import Property
from PySide6.QtGui import QPixmap, QImage, QImageReader, QMovie, QPainter, Qt, QPainterPath, QColor
from qfluentwidgets import ImageLabel, isDarkTheme


class CentreImageLabel(ImageLabel):
    def _postInit(self):
        self.__light_color = QColor(0, 0, 0, 150)
        self.__dark_color = QColor(255, 255, 255, 150)
        self.__enable_mask_color = False
        self.__mask_opacity = 150

    def setImage(self, image: Union[str, QPixmap, QImage] = None):
        self.image = image or QImage()

        if isinstance(image, str):
            reader = QImageReader(image)
            if reader.supportsAnimation():
                self.setMovie(QMovie(image))
            else:
                self.image = reader.read()
        elif isinstance(image, QPixmap):
            self.image = image.toImage()
        self.update()

    def _createPainterPath(self) -> QPainterPath:
        path = QPainterPath()
        w, h = self.width(), self.height()

        # top line
        path.moveTo(self.topLeftRadius, 0)
        path.lineTo(w - self.topRightRadius, 0)

        # top right arc
        d = self.topRightRadius * 2
        path.arcTo(w - d, 0, d, d, 90, -90)

        # right line
        path.lineTo(w, h - self.bottomRightRadius)

        # bottom right arc
        d = self.bottomRightRadius * 2
        path.arcTo(w - d, h - d, d, d, 0, -90)

        # bottom line
        path.lineTo(self.bottomLeftRadius, h)

        # bottom left arc
        d = self.bottomLeftRadius * 2
        path.arcTo(0, h - d, d, d, -90, -90)

        # left line
        path.lineTo(0, self.topLeftRadius)

        # top left arc
        d = self.topLeftRadius * 2
        path.arcTo(0, 0, d, d, -180, -90)
        return path

    def _createPainterImage(self) -> QImage:
        image = self.image.scaled(
            self.size() * self.devicePixelRatioF(),
            Qt.AspectRatioMode.KeepAspectRatioByExpanding,
            Qt.TransformationMode.SmoothTransformation
        )  # type: QImage

        iw, ih = image.width(), image.height()
        w = self.width() * self.devicePixelRatioF()
        h = self.height() * self.devicePixelRatioF()
        x, y = (iw - w) / 2, (ih - h) / 2
        image = image.copy(int(x), int(y), int(w), int(h))
        return image

    def setMaskColor(self, light_color: Union[str, QColor], dark_color: Union[str, QColor]):
        self.__light_color = light_color
        self.__dark_color = dark_color
        self.update()

    def setMaskLightColor(self, light_color: Union[str, QColor]):
        self.__light_color = light_color
        self.update()

    def setMaskDarkColor(self, dark_color: Union[str, QColor]):
        self.__dark_color = dark_color
        self.update()

    def getMaskLightColor(self):
        return self.__light_color

    def getMaskDarkColor(self):
        return self.__dark_color

    def setEnableMask(self, enable: bool):
        self.__enable_mask_color = enable
        self.update()

    def getEnableMask(self):
        return self.__enable_mask_color

    def setMaskOpacity(self, opacity: int):
        self.__mask_opacity = opacity
        self.update()

    def getMaskOpacity(self):
        return self.__mask_opacity

    def paintEvent(self, e):
        painter = QPainter(self)
        painter.setRenderHints(QPainter.RenderHint.Antialiasing)
        painter.setPen(Qt.PenStyle.NoPen)
        painter.setClipPath(self._createPainterPath())
        painter.drawImage(self.rect(), self._createPainterImage())
        if self.enableMask:
            color = self.__dark_color if isDarkTheme() else self.__light_color
            color.setAlpha(self.maskOpacity)
            painter.fillRect(self.rect(), color)
        painter.end()

    enableMask = Property(QColor, getEnableMask, setEnableMask)
    maskOpacity = Property(int, getMaskOpacity, setMaskOpacity)
    maskLightColor = Property(QColor, getMaskLightColor, setMaskLightColor)
    maskDarkColor = Property(QColor, getMaskDarkColor, setMaskDarkColor)
